package com.prodog.gamemodule.fight.damage.util;

import cn.hutool.script.ScriptUtil;
import com.prodog.gamemodule.config.DictConfig;
import com.prodog.gamemodule.config.MapDictConfig;
import com.prodog.gamemodule.fight.action.entity.AtkActionRes;
import com.prodog.gamemodule.fight.fightobj.entity.FightObj;
import com.prodog.gamemodule.fight.fightobj.entity.FightSkill;
import com.prodog.gamemodule.fight.session.FightSession;
import com.prodog.util.MsgTemplateUtil;
import com.prodog.utils.bean.SpringBeanUtils;

import java.util.HashMap;
import java.util.Map;

public class DamageUtil {
    public static String preparedExpression(FightObj obj, FightSkill skill) {
        Map<String, Object> params = new HashMap<>();
        params.put("obj", obj.getFightProp());
        params.putAll(skill.getProp());
        return MsgTemplateUtil.formatStr(skill.getExpression(), params);
    }

    public static long getSkillDamage(FightObj obj, FightSkill skill) {
        String preparedExpression = preparedExpression(obj, skill);
        double damage = Double.parseDouble(String.valueOf(ScriptUtil.eval(preparedExpression)));
        return (long) damage;
    }

    public static void replyHp(FightObj obj, long value) {
        long curHp = obj.getFightProp().getCurHp();
        long maxHp = obj.getFightProp().getHp();
        curHp += value;
        curHp = curHp > maxHp ? maxHp : curHp;
        obj.getFightProp().setCurHp(curHp);
    }

    public static void replyMp(FightObj obj, long value) {
        long curMp = obj.getFightProp().getCurMp();
        long maxMp = obj.getFightProp().getMp();
        curMp += value;
        curMp = curMp > maxMp ? maxMp : curMp;
        obj.getFightProp().setCurMp(curMp);
    }

    public static void consumeHp(FightObj obj, long value) {
        long curHp = obj.getFightProp().getCurHp();
        curHp -= value;
        curHp = curHp < 0 ? 0 : curHp;
        obj.getFightProp().setCurHp(curHp);
        if (curHp == 0) {
            obj.setState(2);
        }
    }

    public static void consumeMp(FightObj obj, long value) {
        long curMp = obj.getFightProp().getCurMp();
        curMp -= value;
        curMp = curMp < 0 ? 0 : curMp;
        obj.getFightProp().setCurMp(curMp);
    }

    public static void executeDamage(FightSession session, FightObj obj, FightObj beActedObj, AtkActionRes res) {
        DictConfig dictConfig = SpringBeanUtils.getBean(DictConfig.class);
        MapDictConfig mapDictConfig = SpringBeanUtils.getBean(MapDictConfig.class);
        FightSkill skill = obj.getSkills().get(obj.getAction().getActionId());
        StringBuilder sb = new StringBuilder();
        sb.append(beActedObj.gName());
        if (skill.getAffectType() == 2) {
            replyHp(beActedObj, res.getTotalDamage(beActedObj.getUuid()));
            sb.append("恢复了" + res.getTotalDamage(beActedObj.getUuid()) + "点" + dictConfig.get("hp") + ",");
        } else {
            if (beActedObj.getAction().getType() == 2) {
                sb.append("防御了,");
            }
            consumeHp(beActedObj, res.getTotalDamage(beActedObj.getUuid()));
            if (beActedObj.getFightProp().getCurHp() <= 0) {
                beActedObj.setState(2);
            }
            sb.append("受到了" + res.getTotalDamage(beActedObj.getUuid()) + "点伤害");
            StringBuilder damageDetail = new StringBuilder();
            damageDetail.append("(");
            res.getDamageMap().get(beActedObj.getUuid()).forEach((k, v) -> {
                damageDetail.append(mapDictConfig.get("damageName", k) + ": " + v.getValue() + ",");
            });
            damageDetail.deleteCharAt(damageDetail.length() - 1);
            damageDetail.append(")");
            sb.append(damageDetail);
            if (beActedObj.getState() == 2) {
                sb.append(",").append(beActedObj.gName()).append("阵亡了");
            }
        }
        session.getObjInfo().addBeActInfo(obj.getUuid(), beActedObj.getUuid(), sb.toString());
        beActedObj.setBeActedDamage(null);
    }
}